package com.quest.space.poker.base.utils;

import com.alibaba.fastjson.JSON;;
import com.quest.space.poker.base.bean.QuestException;
import com.quest.space.poker.base.enums.PokerTypeEnum;
import com.quest.space.poker.base.enums.PokerValueEnum;
import com.quest.space.poker.dto.PlayerDto;
import com.quest.space.poker.dto.PokerDto;
import com.quest.space.poker.dto.TableDto;
import org.springframework.util.CollectionUtils;

import java.util.*;
import java.util.stream.Collectors;

public class PokerUtil {

    /**
     * 从source里选取num个数字
     *
     * @param source
     * @param num
     * @return
     */
    public static List<Integer> getRandomList(List<Integer> source, Integer num) {
        Map<Integer, Integer> map = new HashMap<>();
        int index = 0;
        for (Integer i : source) {
            map.put(index, i);
            index++;
        }
        List<Integer> list = new ArrayList<>(map.keySet());
        Random random = new Random();
        int size = list.size();
        Set<Integer> totals = new HashSet<Integer>();
        while (totals.size() < num) {//获取num个
            int value = random.nextInt(size);
            totals.add(list.get(value));
        }
        return totals.stream().map(map::get).collect(Collectors.toList());
    }

    public static List<PokerDto> sortPokerStr(String content) {
        content = content.replace(" ", "");
        content = content.replace("10", "X");
        char[] chs = content.toCharArray();
        List<PokerDto> list = new ArrayList<>();
        for (char ch : chs) {
            String name = String.valueOf(ch);
            Integer value = PokerValueEnum.getValueByName(name);
            if (value == 0) {
                throw new QuestException();
            }
            list.add(new PokerDto(name, value));
        }
        list.sort(Comparator.comparingInt(PokerDto::getValue));
        return list;
    }

    public static boolean compare(List<PokerDto> current, List<PokerDto> old, String poker, String oldPoker, PokerTypeEnum pokerType) {
        int currentValue = 0;
        int oldValue = 0;
        if (PokerTypeEnum.XXX_Y.equals(pokerType) || PokerTypeEnum.PLANE.equals(pokerType)) {
            currentValue = countValue(current);
            oldValue = countValue(old);
        }else {
            currentValue = current.stream().mapToInt(PokerDto::getValue).sum();
            oldValue = old.stream().mapToInt(PokerDto::getValue).sum();
        }
        if (poker.equals("wW")) {
            currentValue = PokerValueEnum.BIG.getValue() * 4;
        }
        if (oldPoker.equals("wW")) {
            oldValue = PokerValueEnum.BIG.getValue() * 4;
        }
        return currentValue > oldValue;
    }

    private static Integer countValue(List<PokerDto> current) {
        Map<Integer, List<PokerDto>> currentMap = current.stream().collect(Collectors.groupingBy(PokerDto::getValue));
        int currentValue = 0;
        for (Integer key : currentMap.keySet()) {
            List<PokerDto> value = currentMap.get(key);
            if (value.size() >= 3) {
                currentValue += key * value.size();
            }
        }
        return currentValue;
    }

    public static List<PokerDto> remove(List<PokerDto> current, List<PokerDto> allPokers, TableDto table, String playerId) {
        if (CollectionUtils.isEmpty(allPokers)) {
            return allPokers;
        }
        for (PokerDto all : allPokers) {
            for (PokerDto poker : current) {
                if (all.getName().equals(poker.getName()) && !poker.getDelete()) {
                    all.setDelete(true);
                    poker.setDelete(true);
                    break;
                }
            }
        }
        List<PokerDto> pokers = allPokers.stream()
                .filter(p -> !p.getDelete())
                .sorted(Comparator.comparingInt(PokerDto::getValue))
                .collect(Collectors.toList());
        table.setAllPokers(playerId, pokers);
        return pokers;
    }

    public static void print(List<PokerDto> list) {
        System.out.println("牌数：" + JSON.toJSONString(list.stream().map(PokerDto::getName).collect(Collectors.toList())));
    }

    public static void printTable(TableDto table) {
        System.out.println("\n当前牌面:");
        Map<String, List<PokerDto>> map = table.getPokers();
        for (PlayerDto player : table.getPlayers()) {
            String log = JSON.toJSONString(map.get(player.getPlayerId()).stream().map(PokerDto::getName).collect(Collectors.toList()));
            System.out.println(player.getPlayerId() + ":牌型：" + log);
        }
        System.out.println("---------------------------------------------------------------------------------------------------------------------------------\n");
    }


    public static void test(List<PokerDto> test) {
        List<PokerDto> a = new ArrayList<>();
        PokerDto p11 = new PokerDto("2",2);
        a.add(p11);
        test = a;
    }
}
